package com.orgcent.activities;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;
import java.util.TimeZone;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;

import android.app.ListActivity;
import android.app.Service;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.text.Html;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.TextView;
import android.widget.AdapterView.OnItemClickListener;

import com.orgcent.rss.RSSHandler;
import com.orgcent.rss.entity.Channel;
import com.orgcent.rss.entity.Item;
import com.orgcent.util.Tools;

/**
 * 使用SAX方式解析rss中的xml
 */
public class ListViewParseRssXml extends ListActivity implements OnItemClickListener {
	public static final String CONTENT_URL = "content_url";
	private static final String TAG = ListViewParseRssXml.class.getSimpleName();
	private final RSSHandler rssHandler = new RSSHandler();
	
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.list_rss);
		
		getListView().addHeaderView(getLayoutInflater().inflate(R.layout.rss_list_header, null), null, true);
		setListAdapter(new MessageAdapter(rssHandler.getChannel()));
		getListView().setOnItemClickListener(this);
		
		btnOnClick(null);
	}
	
	private final class MessageAdapter extends BaseAdapter {

		private Channel channel;
		
		public MessageAdapter(Channel channel) {
			this.channel = channel;
		}
		
		@Override
		public int getCount() {
			return channel.items.size();
		}

		@Override
		public Object getItem(int position) {
			return channel.items.get(position);
		}

		@Override
		public long getItemId(int position) {
			return position;
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			final ItemViewCache cache;
			if(null == convertView) {
				convertView = getLayoutInflater().inflate(R.layout.list_rss_item, null);
				cache = new ItemViewCache();
				cache.title_tv = Tools.findViewById(convertView, R.id.msg_title_tv);
				cache.desc_tv = Tools.findViewById(convertView, R.id.msg_desc_tv);
				cache.category_tv = Tools.findViewById(convertView, R.id.msg_category_tv);
				cache.pubdate_tv = Tools.findViewById(convertView, R.id.msg_pubdate_tv);
				convertView.setTag(cache);
			} else {
				cache = (ItemViewCache) convertView.getTag();
			}
			Item item = channel.items.get(position);
			cache.title_tv.setText(item.title);
			cache.desc_tv.setText(Html.fromHtml(item.description));
			cache.category_tv.setText(item.category);
//			//将日期转换放到listAdapter.getView()中，在快速滚动ListView时易出现异常，临时在此转换为本地格式
//			if("pubdate".equalsIgnoreCase(tagName)) {  
//				text = Tools.date2str(new Date(text));
//			}
			cache.pubdate_tv.setText(switchPubDate(item.pubdate));   //由于创建很多Date对象，导致程序崩溃
			
			return convertView;
		}
		
		/**
		 * 由于采用new Date('GMT Date')将GMT格式转换为本地时间格式，会创建很多Date对象，快速滑动ListView很容易导致程序崩溃。
		 * 解决方案：使用正则表达式截取GMT时间的年、月、日、时、分、秒，通过Calendar、SimpleDateFormat将其转换为本地日期格式
		 * @param gmt
		 * @return
		 */
		private String switchPubDate(String gmt) {
			initMonthWeekMap();
			
			Matcher m = regex.matcher(gmt);
			if(m.find()) {
				calender.set(Integer.valueOf(m.group(4)), 
						monthWeekMap.get(m.group(3)), 
						Integer.valueOf(m.group(2)),
						Integer.valueOf(m.group(5)),
						Integer.valueOf(m.group(6)),
						Integer.valueOf(m.group(7)));
			}
			m = null;
			return sdf.format(calender.getTime());
		}

		private void initMonthWeekMap() { //初始化月份映射表
			if(monthWeekMap.size() == 0) {
				//导入月份
				monthWeekMap.put("Jan", 0);
				monthWeekMap.put("Feb", 1);
				monthWeekMap.put("Mar", 2);
				monthWeekMap.put("Apr", 3);
				monthWeekMap.put("May", 4);
				monthWeekMap.put("Jun", 5);
				monthWeekMap.put("Jul", 6);
				monthWeekMap.put("Aug", 7);
				monthWeekMap.put("Sep", 8);
				monthWeekMap.put("Oct", 9);
				monthWeekMap.put("Nov", 10);
				monthWeekMap.put("Dec", 11);
			}
		}
		final Pattern regex = Pattern.compile(date_pattern);
		final static String date_pattern = "^([A-Z]{1}[a-z]{2}), ([0-9]{1,2}) ([A-Z]{1}[a-z]{2}) ([0-9]{4}) ([0-9]{2}):([0-9]{2}):([0-9]{2}) GMT$";
		final Map<String,Integer> monthWeekMap = new HashMap<String,Integer>();
		final Calendar calender = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
		final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		
		class ItemViewCache  {
			TextView title_tv;
			TextView desc_tv;
			TextView category_tv;
			TextView pubdate_tv;
		}
	}

	public void btnOnClick(View view) {
		//异步加载数据
		getListView().postDelayed(new Runnable() {
			
			@Override
			public synchronized void run() {
				final long now = System.currentTimeMillis();
				if(now - lastUpdate < 10000) { //两次更新时间间隔不小于10秒时才更新
					return;
				}
				processRefreshData();
				lastUpdate = now;
			}
		},1000);
	}

	static long lastUpdate;

	private void processRefreshData() {
		ConnectivityManager cm = (ConnectivityManager) getSystemService(Service.CONNECTIVITY_SERVICE);
		// 是否可以联网
		NetworkInfo ninfo = cm.getActiveNetworkInfo(); 
		// 网络可用
		if (ninfo != null && ninfo.isAvailable()) {
			String uri = "http://www.cnbeta.com/backend.php";
//			String uri = "http://www.cnbeta.com/commentrss.php";
			 String content = getContent(uri);
			 if(TextUtils.isEmpty(content)) {
				 Tools.toastShow(this, "网络连接超时");
				 return;
			 }
			 rssHandler.parse(content);
			
			((MessageAdapter)getListAdapter()).notifyDataSetChanged(); 
			String description = rssHandler.getChannel().description;
			if(!TextUtils.isEmpty(description)) {
				this.setTitle(description);
			}
		} else {
			Tools.toastShow(this, "网络不可用");
		}
	}

	
	// 获取网络内容
	private String getContent(String uri) {
		Log.i(TAG, "uri:" + uri);
		HttpClient client = new DefaultHttpClient();
		HttpGet get = new HttpGet(uri);
		HttpResponse resp;
		HttpParams  params = client.getParams(); //超时时间
		HttpConnectionParams.setConnectionTimeout(params, 10000);// Set the default socket timeout (SO_TIMEOUT) // in milliseconds which is the timeout for waiting for data.  
//	    HttpConnectionParams.setSoTimeout(params, 15000);  
		
		StringBuilder content = new StringBuilder();
		try {
			resp = client.execute(get);
			HttpEntity entity = resp.getEntity();
			BufferedReader reader = new BufferedReader(new InputStreamReader(
					entity.getContent(),"utf-8"));
			String line;
			while ((line = reader.readLine()) != null) {
				content.append(line);
//				Log.i(TAG, "line : " + line);
			}
			reader.close();
			entity = null;
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			client.getConnectionManager().shutdown();
		}

		return content.toString();
	}

	@Override
	public void onItemClick(AdapterView<?> parent, View view, int position,
			long id) {
		final Intent intent = new Intent(this,WebViewHTML.class);
		String link = ((Item)getListAdapter().getItem(position-1)).link; //由于开头加了header
		intent.putExtra(CONTENT_URL, link);
		startActivity(intent);
	}
}
